<?php

/**
 * 接口类
 */
class MInterface {
	private $url = ''; // b2c 接口地址
	private $api_key = '';
	private $api_secret = '';

	private $ver = '2.0'; // 接口版本
	private $format = 'json'; // 接口返回数据格式
	private $gzip = 1; // 是否开启gzip
	public static $timestamp = NULL;
	public static $time_offset = NULL;
	private static $mem = NULL;
	public static $login_id = NULL;
	public static $user_token = NULL;
	public static $exe_count = array();

	/* 设置http请求参数 */
	private $dataformat = 'json';
	// private $decode_json = TRUE;
	private $connecttimeout = 30;
	private $timeout = 30;
	private $debug = false;

	// 错误列表
	private static $error_list = array(
	);

	/**
	 * 初始化接口请求参数
	 */
	public function __construct($server = array()) {
		foreach(( array ) $server as $key => $val ) {
			if(! empty( $val )) {
				$this->{$key} = $val;
			}
		}

		//$this->init();
	}

	/**
	 * 初始化接口参数
	 */
	private function init() {
		//$this->params['api_key'] = $this->api_key;
		//$this->params['ver'] = $this->ver;
		//$this->params['format'] = $this->format;
		//$this->params['gzip'] = $this->gzip;

		// 设置时间
		$this->set_time();
	}

	/**
	 * 设置时间
	 */
	private function set_time() {
		/* 计算服务器时间与本地时间偏差值 */
		self::$time_offset = wap_getcookie( "time_offset", false );

		if(self::$time_offset == null || self::$time_offset > 600 || self::$time_offset < - 600) {
			// 获取服务器时间
			$server_time = $this->getUtilsTime();

			// 兼容正式、测试环境获取服务器时间接口
			if(is_array( $server_time ) && array_key_exists( 'time', $server_time )) {
				$server_time = $server_time['time'];
			}

			// 服务器时间 - 本地时间 = 差值，(接受10min时差)
			if($server_time) {
				self::$time_offset = $server_time - $_SERVER['REQUEST_TIME'];
				if(self::$time_offset >= - 600 && self::$time_offset <= 600) {
					if(self::$time_offset == 0) {
						self::$time_offset = 1;
					}
					setcookie( "time_offset", self::$time_offset, 0, COOKIE_PATH, COOKIE_DOMAIN );
				} else {
					self::$time_offset = 0;
				}
			} else {
				self::$time_offset = 0;
			}
		}

		$this->params['timestamp'] = $_SERVER['REQUEST_TIME'] + self::$time_offset;
	}


	/**
	 * 发送http请求
	 *
	 * @param string $url
	 * @param string $method
	 * @param array $postfields
	 * @return string
	 */
	private function http($url, $method, $postfields = NULL) {
		$ci = curl_init();
		curl_setopt( $ci, CURLOPT_URL, $url );
		curl_setopt( $ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout ); // 连接超时
		curl_setopt( $ci, CURLOPT_TIMEOUT, $this->timeout ); // 执行超时
		if(function_exists('real_ip'))
		{
			$clientIp=real_ip();
			if($clientIp)
			{
				$header = array('CLIENT-IP:'.$clientIp,	'X-Forwarded-For:'.$clientIp,); //客户端IP
				curl_setopt($ci, CURLOPT_HTTPHEADER, $header);
			}
		}
		curl_setopt( $ci, CURLOPT_RETURNTRANSFER, true ); // 文件流的形式返回，而不是直接输出
		// curl_setopt($ci, CURLOPT_ENCODING, "gzip");
		curl_setopt( $ci, CURLOPT_HEADER, FALSE );

		if('POST' == $method) {
			curl_setopt( $ci, CURLOPT_POST, true ); // post
		}

		if(! empty( $postfields )) {
			curl_setopt( $ci, CURLOPT_POSTFIELDS, $postfields ); // post数据 可为数组、连接字串
		}

		$response = curl_exec( $ci );

		$error_codes = array(
			1 => 'CURLE_UNSUPPORTED_PROTOCOL',
			2 => 'CURLE_FAILED_INIT',
			3 => 'CURLE_URL_MALFORMAT',
			4 => 'CURLE_URL_MALFORMAT_USER',
			5 => 'CURLE_COULDNT_RESOLVE_PROXY',
			6 => 'CURLE_COULDNT_RESOLVE_HOST',
			7 => 'CURLE_COULDNT_CONNECT',
			8 => 'CURLE_FTP_WEIRD_SERVER_REPLY',
			9 => 'CURLE_REMOTE_ACCESS_DENIED',
			11 => 'CURLE_FTP_WEIRD_PASS_REPLY',
			13 => 'CURLE_FTP_WEIRD_PASV_REPLY',
			14 => 'CURLE_FTP_WEIRD_227_FORMAT',
			15 => 'CURLE_FTP_CANT_GET_HOST',
			17 => 'CURLE_FTP_COULDNT_SET_TYPE',
			18 => 'CURLE_PARTIAL_FILE',
			19 => 'CURLE_FTP_COULDNT_RETR_FILE',
			21 => 'CURLE_QUOTE_ERROR',
			22 => 'CURLE_HTTP_RETURNED_ERROR',
			23 => 'CURLE_WRITE_ERROR',
			25 => 'CURLE_UPLOAD_FAILED',
			26 => 'CURLE_READ_ERROR',
			27 => 'CURLE_OUT_OF_MEMORY',
			28 => 'CURLE_OPERATION_TIMEDOUT',
			30 => 'CURLE_FTP_PORT_FAILED',
			31 => 'CURLE_FTP_COULDNT_USE_REST',
			33 => 'CURLE_RANGE_ERROR',
			34 => 'CURLE_HTTP_POST_ERROR',
			35 => 'CURLE_SSL_CONNECT_ERROR',
			36 => 'CURLE_BAD_DOWNLOAD_RESUME',
			37 => 'CURLE_FILE_COULDNT_READ_FILE',
			38 => 'CURLE_LDAP_CANNOT_BIND',
			39 => 'CURLE_LDAP_SEARCH_FAILED',
			41 => 'CURLE_FUNCTION_NOT_FOUND',
			42 => 'CURLE_ABORTED_BY_CALLBACK',
			43 => 'CURLE_BAD_FUNCTION_ARGUMENT',
			45 => 'CURLE_INTERFACE_FAILED',
			47 => 'CURLE_TOO_MANY_REDIRECTS',
			48 => 'CURLE_UNKNOWN_TELNET_OPTION',
			49 => 'CURLE_TELNET_OPTION_SYNTAX',
			51 => 'CURLE_PEER_FAILED_VERIFICATION',
			52 => 'CURLE_GOT_NOTHING',
			53 => 'CURLE_SSL_ENGINE_NOTFOUND',
			54 => 'CURLE_SSL_ENGINE_SETFAILED',
			55 => 'CURLE_SEND_ERROR',
			56 => 'CURLE_RECV_ERROR',
			58 => 'CURLE_SSL_CERTPROBLEM',
			59 => 'CURLE_SSL_CIPHER',
			60 => 'CURLE_SSL_CACERT',
			61 => 'CURLE_BAD_CONTENT_ENCODING',
			62 => 'CURLE_LDAP_INVALID_URL',
			63 => 'CURLE_FILESIZE_EXCEEDED',
			64 => 'CURLE_USE_SSL_FAILED',
			65 => 'CURLE_SEND_FAIL_REWIND',
			66 => 'CURLE_SSL_ENGINE_INITFAILED',
			67 => 'CURLE_LOGIN_DENIED',
			68 => 'CURLE_TFTP_NOTFOUND',
			69 => 'CURLE_TFTP_PERM',
			70 => 'CURLE_REMOTE_DISK_FULL',
			71 => 'CURLE_TFTP_ILLEGAL',
			72 => 'CURLE_TFTP_UNKNOWNID',
			73 => 'CURLE_REMOTE_FILE_EXISTS',
			74 => 'CURLE_TFTP_NOSUCHUSER',
			75 => 'CURLE_CONV_FAILED',
			76 => 'CURLE_CONV_REQD',
			77 => 'CURLE_SSL_CACERT_BADFILE',
			78 => 'CURLE_REMOTE_FILE_NOT_FOUND',
			79 => 'CURLE_SSH',
			80 => 'CURLE_SSL_SHUTDOWN_FAILED',
			81 => 'CURLE_AGAIN',
			82 => 'CURLE_SSL_CRL_BADFILE',
			83 => 'CURLE_SSL_ISSUER_ERROR',
			84 => 'CURLE_FTP_PRET_FAILED',
			84 => 'CURLE_FTP_PRET_FAILED',
			85 => 'CURLE_RTSP_CSEQ_ERROR',
			86 => 'CURLE_RTSP_SESSION_ERROR',
			87 => 'CURLE_FTP_BAD_FILE_LIST',
			88 => 'CURLE_CHUNK_FAILED'
		);

		$curl_err = null;
		if(in_array(curl_error($ci), $error_codes)){
			$curl_err = curl_errno( $ci );
		}

		if($this->debug) {
			echo "=====post data======\r\n";
			var_dump( $postfields );

			echo '=====info=====' . "\r\n";
			print_r( curl_getinfo( $ci ) );

			echo '=====$response=====' . "\r\n";
			print_r( $response );
		}
		curl_close( $ci );

		// curl执行错误日志
		if($curl_err) {
			// 错误代码
			$logfilename = ROOT_PATH . DATA_DIR . '/logs/error_interface_http_' . date( 'Y_m_d' ) . '.log';
			$str = date( 'Y-m-d H:i:s' ) . "\t" . $error_codes[$curl_err] . '(' . $curl_err . ')' ."\t".$url."\t".var_export($postfields)."\r\n";

			if(PHP_VERSION >= '5.0') {
				file_put_contents( $logfilename, $str, FILE_APPEND );
			} else {
				$fp = @fopen( $logfilename, 'ab+' );
				if($fp) {
					fwrite( $fp, $str );
					fclose( $fp );
				}
			}
		}

		/* curl发生错误,但不为超时和接收失败，则使用file_get_contents方法 */
		if($curl_err && ! in_array( $curl_err, array(28,56) )) {
			if('POST' == $method) {
				$context['http'] = array(
						'method' => 'POST',
						'content' => $postfields
				);
				$response = file_get_contents( $url, false, stream_context_create( $context ) );
			} else {
				$response = file_get_contents( $url );
			}
		}

		/* 解码返回的json串 */
		$response = trim( $response );
		if(!empty( $response ) && is_string( $response ) && in_array($response[0], array('[','{'))) {
			$response = json_decode( $response, true );
		} else if(in_array( $response, self::$error_list )) {
			// 重新获取时间
			if($response == 'TIMESTAMP_OUT_OF_RANGE' || $response == 'TIMESTAMP_TIMEOUT') {
				setcookie( "time_offset", 0, local_time() - 86400, COOKIE_PATH, COOKIE_DOMAIN );
				$this->set_time();
			}
			$response = false;
		}

		return $response;
	}

	/**
	 * 执行接口调用
	 *
	 * @param array $params		发送请求需要传递的参数
	 * @param string $method	请求发送方式
	 */
	private function execute($params, $method = 'GET') {
		if(empty( $params ) || ! is_array( $params )) {
			return false;
		}

		//$params = array_merge( $params, $this->params );

		$url = empty( $params['url'] ) ? $this->url : $params['url'];

		// 选择请求方式
		switch($method) {
			case 'GET' :
				$url = $url . '?' . http_build_query( $params );
				$response = $this->http( $url, 'GET' );
				break;
			default :
				if(is_array( $params ) || is_object( $params )) {
					$body = http_build_query( $params );
				}
				$response = $this->http( $url, $method, $body );
		}
		//var_dump(urldecode($url)) ;// $response['urlx']=$url;

		if(isset( $params['service'] ) && isset( self::$exe_count[$params['service']] )) {
			self::$exe_count[$params['service']] += 1;
		} else if(isset( $params['service'] )) {
			self::$exe_count[$params['service']] = 1;
		}

		return $response;
	}


	/**
	 * 用户注册
	 */
	public function addUserBase($login_id, $password, $gender = '0') {
		$params['service'] = "shop.register";

		// 登录ID
		if(empty( $login_id ))
		return false;
		else
		$params['login_id'] = $login_id;

		// 密码
		if(empty( $password ))
		return false;
		else
		$params['password'] = ($password);

		// 性别
		//$params['gender'] = $gender;

		// 生日
		//$params['birthday'] = $birthday;

		// 返回字段
		if(! empty( $fields ) && is_string( $fields ))
		$params['fields'] = $fields;
		else
		$params['fields'] = 'user_token,user_name,user_integral';

		$response = $this->execute( $params );
		return $response;
	}

	/**
	 * 用户基本资料
	 */
	public function getUserBaseInfo($user_token, $fields = '') {
		$params['service'] = "shop.user.info.get";

		// 用户ID
		if(empty( $user_token )){
			return false;
		}else{
			$params['user_token'] = $user_token;
		}

		// 返回字段
		if(! empty( $fields ) && is_string( $fields ))
		$params['fields'] = $fields;
		else
		$params['fields'] = 'id, userName,phone,email, RegioninfoVO province,RegioninfoVO city,RegioninfoVO district';

		$response = $this->execute( $params );
		return $response;
	}

	/**
	 * 修改用户基本资料
	 */
	public function updateUserBaseInfo($user_token, $userName, $phone, $email, $province_id, $city_id, $district_id){
		$params['service'] = "shop.user.info.update";

		// 用户ID
		if(empty( $user_token )){
			return false;
		}else{
			$params['user_token'] = $user_token;
		}

		$params['userName'] = $userName;
		$params['phone'] = $phone;
		$params['email'] = $email;
		$params['province_id'] = $province_id;
		$params['city_id'] = $city_id;
		$params['district_id'] = $district_id;

		$response = $this->execute( $params );
		return $response;
	}

	/**
	 * 修改用户密码
	 */
	public function modifyUserPassword($user_token, $old_password, $new_password){
		$params['service'] = "shop.user.password.modify";

		// 用户ID
		if(empty( $user_token )){
			return false;
		}else{
			$params['user_token'] = $user_token;
		}

		// 旧密码
		if(empty( $old_password )){
			return false;
		}else{
			$params['old_password'] = $old_password;
		}

		// 新密码
		if(empty( $new_password )){
			return false;
		}else{
			$params['new_password'] = $new_password;
		}

		$response = $this->execute( $params );
		return $response;
	}


	/**
	 * 用户登录
	 */
	public function loginUserBase($login_id, $password, $fields = '') {
		$params['service'] = "shop.login";

		// 用户名
		if(empty( $login_id ))
		return false;
		else
		$params['login_id'] = $login_id;

		// 密码
		if(empty( $password ))
		return false;
		else
		$params['password'] = $password;

		// 返回字段
		if(! empty( $fields ) && is_string( $fields ))
		$params['fields'] = $fields;
		else
		$params['fields'] = 'user_token,user_name,user_integral';

		$response = $this->execute( $params );
		return $response;
	}


	/**
	 * 关于我们
	 */
	public function aboutUs(){
		$params['service'] = "shop.about.get";

		$params['fields'] = "about_html";

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 服务条款
	 */
	public function serviceTerm(){
		$params['service'] = "shop.service.term";

		$params['fields'] = "service_term_html";

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 首页档期导航接口
	 */
	public function getIndex(){
		$params['service'] = "shop.index.get";

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 获取三级地址
	 */
	public function getShopArea($province_id=0, $city_id=0, $district_id=0){
		$params['service'] = "shop.area.get";

		if (!empty($province_id))$params['province_id'] = $province_id;
		if (!empty($city_id))$params['city_id'] = $city_id;
		if (!empty($district_id))$params['district_id'] = $district_id;

		$response = $this->execute($params);

		$response = ($response['status'] && is_array($response['result'])) ? $response['result'] : array();

		return $response;
	}

	/**
	 * 搜索接口
	 */
	public function search($keyword, $page=1, $page_size=100){
		$params['service'] = "shop.product.search";

		$params['keyword'] = $keyword;
		$params['page'] = $page;
		$params['page_size'] = $page_size;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 商品列表
	 */
	public function getProductList($index_id, $category_id, $page=1, $page_size=100){
		$params['service'] = "shop.products.get";

		$params['index_id'] = $index_id;
		$params['category_id'] = $category_id;
		$params['page'] = $page;
		$params['page_size'] = $page_size;

		$response = $this->execute($params);

		return $response;
	}


	/**
	 * 商品详情
	 */
	public function getProductDetail($product_id){
		$params['service'] = "shop.product.get";

		$params['product_id'] = $product_id;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 类目
	 */
	public function getCategory(){
		$params['service'] = "shop.category.get";

		$params['product_id'] = $product_id;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 获取用户收货地址
	 */
	public function getUserAddress($user_token){
		$params['service'] = "shop.user.address.get";

		$params['user_token'] = $user_token;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 添加用户收货地址
	 */
	public function addUserAddress($user_token, $consignee, $province_id, $city_id, $district_id, $address, $mobile, $telephone, $postcode){
		$params['service'] = "shop.user.address.add";

		$params['user_token'] = $user_token;
		$params['consignee'] = $consignee;
		$params['province_id'] = $province_id;
		$params['city_id'] = $city_id;
		$params['district_id'] = $district_id;
		$params['address'] = $address;
		$params['mobile'] = $mobile;
		$params['telephone'] = $telephone;
		$params['postcode'] = $postcode;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 修改用户收货地址
	 */
	public function updateUserAddress($user_token, $address_id, $consignee, $province_id, $city_id, $district_id, $address, $mobile, $telephone, $postcode){
		$params['service'] = "shop.user.address.update";

		$params['user_token'] = $user_token;
		$params['address_id'] = $address_id;
		$params['consignee'] = $consignee;
		$params['province_id'] = $province_id;
		$params['city_id'] = $city_id;
		$params['district_id'] = $district_id;
		$params['address'] = $address;
		$params['mobile'] = $mobile;
		$params['telephone'] = $telephone;
		$params['postcode'] = $postcode;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 删除用户收货地址
	 */
	public function delUserAddress($user_token, $address_id){
		$params['service'] = "shop.user.address.delete";

		$params['user_token'] = $user_token;
		$params['address_id'] = $address_id;

		$response = $this->execute($params);

		return $response;
	}

	/**
	 * 结算确认
	 */
	public function comfirmOrder($user_token, $cart_product){
		$params['service'] = "shop.user.address.delete";

		$params['user_token'] = $user_token;
		$params['cart_product'] = $cart_product;

		$response = $this->execute($params);

		return $response;
	}

}

?>
